package com.smit.livevideo.sample.player;

import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.smit.player.SmitPlayer;
import com.smit.utils.LogUtil;

import java.io.IOException;

/**
 * Created by smfang on 2015/11/24. mediaplayer控制器
 */
public class PlayerThread extends Thread
        implements SurfaceHolder.Callback, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener,
        MediaPlayer.OnInfoListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnVideoSizeChangedListener
{
    private static final String TAG = PlayerThread.class.getSimpleName();
    private static final int MSG_PLAYER_RESET = 101;
    private static final int MSG_PLAYER_START = 102;
    private static final int MSG_PLAYER_STOP = 103;
    private static final int MSG_PLAYER_RESET_AND_PREPARE = 105;
    private static final int MSG_PLAYER_PREPARE_TIME_OUT = 106;
    private static PlayerHandler mHandler = null;
    private static MediaPlayer player = null;
    protected boolean bPlayerError = false;
    private boolean bPlayerHasReset = false;
    private SurfaceHolder surfaceHolder;
    private HideFullBack hideFullBack = null;
    private Looper msgLooper;

    /**
     * 构造函数
     */
    public PlayerThread()
    {
        initMediaPlayer();
    }

    private void initMediaPlayer()
    {
        if (player == null)
        {
            player = SmitPlayer.getPlayer();
            player.setOnCompletionListener(this);
            player.setOnErrorListener(this);
            player.setOnInfoListener(this);
            player.setOnPreparedListener(this);
            player.setOnVideoSizeChangedListener(this);
        }
    }

    public void setPlayerHasReset(boolean bPlayerHasReset)
    {
        this.bPlayerHasReset = bPlayerHasReset;
    }

    /**
     * 设置播放surfaceHolder
     * @param surfaceView 显示mediaplayer的视图
     */
    public void setSurfaceHolder(SurfaceView surfaceView)
    {
        if (surfaceView != null)
        {
            surfaceHolder = surfaceView.getHolder();
            surfaceHolder.addCallback(this);
        }
    }

    /**
     * 设置播放surfaceHolder
     * @param surfaceView 显示mediaplayer的视图
     * @param hideFullBack 回调控制UI
     */
    public void setSurfaceHolder(SurfaceView surfaceView, HideFullBack hideFullBack)
    {
        if (surfaceView != null)
        {
            surfaceHolder = surfaceView.getHolder();
            surfaceHolder.addCallback(this);
        }

        this.hideFullBack = hideFullBack;

        return;
    }

    public MediaPlayer getPlayer()
    {
        return player;
    }

    /**
     * 释放mediaPlayer资源
     */
    public void freePlayer()
    {
        player.release();
        player = null;
        releaseHandler();
        freeSurfaceHolder();
        SingleTonHolder.instance = null;
    }

    private void freeSurfaceHolder()
    {
        surfaceHolder = null;
    }

    /**
     * 获取mediaplayer的状态
     * @return boolean
     */
    public boolean isbPlayerError()
    {
        return bPlayerError;
    }

    /**
     * 设置mediaplayer的状态
     * @param bMediaPlayerError 是否出错
     */
    public void setbPlayerError(boolean bMediaPlayerError)
    {
        this.bPlayerError = bMediaPlayerError;
    }

//    private static MediaPlayerController getInstance()
//    {
//        return SingleTonHolder.instance;
//    }

    /**
     * 消息处理线程
     */
    public void run()
    {
        Looper.prepare();
        msgLooper = Looper.myLooper();
        mHandler = new PlayerHandler();
        Looper.loop();
    }

    /**
     * 移除所有message
     */
    public void removeAllMessage()
    {
        mHandler.removeCallbacksAndMessages(null);
    }

    /**
     * 移除reset player的消息
     */
    public void removeResetPrepareMessage()
    {
        mHandler.removeMessages(MSG_PLAYER_RESET_AND_PREPARE);
    }

    /**
     * 发送复位并且准备player消息
     */
    public void resetAndPreparePlayer()
    {
        mHandler.sendEmptyMessage(MSG_PLAYER_RESET_AND_PREPARE);
    }

    /**
     * 发送player准备超时消息
     * @param delay 延迟的时间
     */
    public static void prepareTimeOut(int delay)
    {
        mHandler.sendEmptyMessageDelayed(MSG_PLAYER_PREPARE_TIME_OUT, delay);
    }

    /**
     * 发送复位player消息
     */
    public void resetPlayer()
    {
        mHandler.sendEmptyMessage(MSG_PLAYER_RESET);
    }

    /**
     * 发送停止player消息
     */
    public void stopPlayer()
    {
        mHandler.sendEmptyMessage(MSG_PLAYER_STOP);
    }

    /**
     * 启动player
     */
    public void startPlayer()
    {
        mHandler.sendEmptyMessage(MSG_PLAYER_START);
    }

    /**
     * 释放player处理消息循环
     */
    private void releaseHandler()
    {
        mHandler.removeCallbacksAndMessages(null);
        msgLooper.quit();
        mHandler = null;
    }

    /**
     * 停止player
     */
    private void doStop()
    {
        if (player != null && player.isPlaying())
        {
            player.stop();
        }
    }

    /**
     * 启动player
     */
    private void doStart()
    {
        if (player != null)
        {
            LogUtil.trace(TAG, "doStart");
            player.start();
        }
    }

    /**
     * 复位player
     */
    private void doReset()
    {
        if (player != null && bPlayerHasReset == false)
        {
            LogUtil.trace(TAG, "doReset");
            bPlayerHasReset = true;
            player.reset();
        }
    }

    /**
     * 复位并且准备player
     */
    private void doResetAndPrepare()
    {
        try
        {
            if (player == null)
            {
                return;
            }
            if (bPlayerHasReset == false)
            {
                LogUtil.trace(TAG, "reset");
                bPlayerHasReset = true;
                player.reset();
            }
            // LiveVideoPlayer.setPlayerType(mediaPlayer,LiveVideoPlayer.MTK_CMPB_PLAYER_TYPE);
            LogUtil.trace(TAG, "setDataSource");
            SmitPlayer.updateDataSource();
            LogUtil.trace(TAG, "prepare");
            player.prepareAsync();
            bPlayerHasReset = false;
            // mediaPlayer.prepare();//prepare速度快，但是容易导致TCL media_server死机
        }
        catch (IllegalArgumentException e)
        {
            bPlayerHasReset = false;
            LogUtil.error(TAG, "IllegalArgumentException");
        }
        catch (IllegalStateException e)
        {
            bPlayerHasReset = false;
            LogUtil.error(TAG, "IllegalStateException");
        }
        catch (IOException e)
        {
            bPlayerHasReset = false;
            LogUtil.error(TAG, "IOException");
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra)
    {
        LogUtil.trace(TAG, "onError Called");
        if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED)
        {
            LogUtil.error(TAG, "Media Error, Server Died " + extra);
        }
        else if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN)
        {
            LogUtil.error(TAG, "Media Error, Error Unknown " + extra);
        }
        else
        {
            LogUtil.error(TAG, "Media Error, Error whatError:" + what + "extra:" + extra);
        }
        bPlayerError = true;
        bPlayerHasReset = false;
        return false;
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra)
    {
        if (what == MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING)
        {
            LogUtil.trace(TAG, "Media Info, Media Info Bad Interleaving " + extra);
        }
        else if (what == MediaPlayer.MEDIA_INFO_NOT_SEEKABLE)
        {
            LogUtil.trace(TAG, "Media Info, Media Info Not Seekable " + extra);
        }
        else if (what == MediaPlayer.MEDIA_INFO_UNKNOWN)
        {
            LogUtil.trace(TAG, "Media Info, Media Info Unknown " + extra);
        }
        else if (what == MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING)
        {
            LogUtil.trace(TAG, "MediaInfo, Media Info Video Track Lagging " + extra);
        }
        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mp)
    {
        LogUtil.trace(TAG, "onPrepared Called");
        startPlayer();

        if (hideFullBack != null)
        {
            hideFullBack.hideFullBackCallback();
        }

        LogUtil.trace(TAG, "onPrepared msgResetPlayerNu=0,mp.start()!");

    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height)
    {
        LogUtil.trace(TAG, "onVideoSizeChanged Called");
    }

    @Override
    public void onCompletion(MediaPlayer mp)
    {
        LogUtil.trace(TAG, "onCompletion Called");
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        LogUtil.trace(TAG, "surfaceCreated Called");
        if (player != null)
        {
            player.setDisplay(holder);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
        LogUtil.trace(TAG, "surfaceChanged Called");
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        LogUtil.trace(TAG, "surfaceDestroyed Called");
    }

    /**
     * 隐藏黑色遮罩回调接口
     */
    public interface HideFullBack
    {
        /**
         * 隐藏黑遮罩
         */
        public void hideFullBackCallback();
    }

    /**
     * 内部类
     */
    private class PlayerHandler extends Handler
    {
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case MSG_PLAYER_RESET_AND_PREPARE:
                    LogUtil.trace(TAG, "get reset msg msgResetPlayerNum=1,now reset player");
                    doResetAndPrepare();
                    break;
                case MSG_PLAYER_RESET:
                    doReset();
                    break;
                case MSG_PLAYER_STOP:
                    doStop();
                    break;
                case MSG_PLAYER_START:
                    doStart();
                    break;
                default:
                    break;
            }
        }
    }

    private static class SingleTonHolder
    {
        private static PlayerThread instance = new PlayerThread();
    }
}
